# plugs/udp.py
#
#

""" implement listenudp thread """

__copyright__ = 'this file is in the public domain'

from gozerbot.fleet import fleet
from gozerbot.generic import rlog, handle_exception
from gozerbot.config import config
from gozerbot.plughelp import plughelp
import gozerbot.thr as thr
import socket, re, time

plughelp.add('udp' , 'run the udp listen thread')

class Udplistener(object):
    """ listen for udp messages """
    def __init__(self):
        self.stop = 0
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        except:
            pass
        self.sock.setblocking(1)
        self.sock.settimeout(1)

    def listen(self, botname):
        """ listen for udp messages .. /msg via bot"""
        if not config['udp']:
            rlog(0, 'udp', 'udp not enabled')
            return
        try:
            self.bot = fleet.byname(botname)
            if not self.bot:
                rlog(10, 'udp', "can't find bot named %s" % botname)
                return
            self.sock.bind((config['udphost'], config['udpport']))
            rlog(10, 'udp', 'udp listening on %s %s' % (config['udphost'], \
config['udpport']))
            self.stop = 0
        except IOError:
            handle_exception()
            self.sock = None
            self.stop = 1
            return
        # loop on listening udp socket
        self.bot.connected.wait()
        while not self.stop:
            try:
                data, addr = self.sock.recvfrom(400)
            except socket.timeout:
                continue
            # check if udp is enabled and source ip is in udpallow list
            if config['udp'] and addr[0] in config['udpallow']:
                # get printto and passwd data
                header = re.search('(\S+) (\S+) (.*)', data)
                if header:
                    # check password
                    if header.group(1) == config['udppassword']:
                        printto = header.group(2)    # is the nick/channel
                        # check if printto is in allowednicks
                        if not printto in config['udpallowednicks']:
                            continue
                        rlog(10, 'udp', str(addr[0]) +  " udp allowed")
                        text = header.group(3)    # is the text
                        time.sleep(3)
                        self.bot.say(printto, text)
                    else:
                        rlog(10, 'udp', "can't match udppasswd from " + \
str(addr))
                else:
                    rlog(10, 'udp', "can't match udp from " + str(addr[0]))
            else:
                rlog(10, 'udp', 'denied udp from ' + str(addr[0]))
        rlog(10, 'udp', 'shutting down udplistener')
        self.sock.close()

udplistener = Udplistener()

def init():
    """ init the plugin """
    thr.start_new_thread(udplistener.listen, ('main',))
    return 1
    
def shutdown():
    """ shutdown the plugin """
    udplistener.stop = 1
    time.sleep(3)
    return 1
